﻿// 值参数和引用参数的区别
// 一、值参数：
// 1.在栈中为形参分配空间
// 2.将实参的值复制给形参
//namespace cs_basic_05
//{
//    class MyClass
//    {
//        public int Val = 20;
//    }
//    internal class Program
//    {
//        static void MyMethod(MyClass f1, int f2)
//        {
//            f1.Val = f1.Val + 5;
//            f2 = f2 + 5;
//            Console.WriteLine($"f1.val:{f1.Val},f2:{f2}");
//        }
//        static void Main(string[] args)
//        {
//            MyClass a1 = new MyClass();
//            int a2 = 5;
//            MyMethod(a1, a2);
//            Console.WriteLine($"f1.val:{a1.Val},f2:{a2}");
//        }

//    }
//}
// 应该输出：
// f1.Val:25，f2:10 
// f1.Val:25，f2:5 
// 结果一致，证明结束



// 二、引用参数
// 1. 使用引用参数时，必须在方法的声明和调用中都使用ref修饰符
// 2. 实参必须是变量，在用作实参前必须被赋值。如果是引用类型变量可以赋值NULL
// 3. 不会在栈上为形参分配内存
// 4. 形参的参数名将作为实参变量的别名，指向相同的内存空间

//namespace cs_basic_05
//{
//    class MyClass
//    {
//        public int Val = 20;
//    }
//    internal class Program
//    {
//        static void MyMethod(ref MyClass f1,ref int f2)
//        {
//            f1.Val = f1.Val + 5;
//            f2 = f2 + 5;
//            Console.WriteLine($"f1.val:{f1.Val},f2:{f2}");
//        }
//        static void Main(string[] args)
//        {
//            MyClass a1 = new MyClass();
//            int a2 = 5;
//            MyMethod(ref a1,ref a2);
//            Console.WriteLine($"f1.val:{a1.Val},f2:{a2}");
//        }
//    }
//}

// 应该输出：
// f1.Val:25，f2:10 
// f1.Val:25，f2:10
// 结果一致，证明结束

// 引用类型作为值参数和引用参数



// 三、引用类型作为值参数和引用类型参数
//using System.Diagnostics.Metrics;
//using System.Security.Cryptography.X509Certificates;

//namespace cs_basic_05
//{
//    class MyClass
//    {
//        public int Val = 20;
//    }
//    class Program
//    {
//        static void RefAsParameter(MyClass f1)
//        {
//            f1.Val = 50;
//            Console.WriteLine($"Bfter member assigment:{f1.Val}");
//            f1 = new MyClass();
//            Console.WriteLine($"After member assigment:{f1.Val}");
//        }
//        static void Main(string[] args)
//        {
//            MyClass a1 = new MyClass();
//            Console.WriteLine($"Before method call:{a1.Val}");
//            RefAsParameter(a1);
//            Console.WriteLine($"After method call:{a1.Val}");
//        }
//    }
//}

/*
预计结果：
    Before method call:20
    Bfter member assigment:50
    After member assigment:20
    After method call:50
结果一致，证明完毕
*/


//namespace cs_basic_05
//{
//    class MyClass
//    {
//        public int Val = 20;
//    }
//    class Program
//    {
//        static void RefAsParameter(ref MyClass f1)
//        {
//            f1.Val = 50;
//            Console.WriteLine($"Bfter member assigment:{f1.Val}");
//            f1 = new MyClass();
//            Console.WriteLine($"After member assigment:{f1.Val}");
//        }
//        static void Main(string[] args)
//        {
//            MyClass a1 = new MyClass();
//            Console.WriteLine($"Before method call:{a1.Val}");
//            RefAsParameter(ref a1);
//            Console.WriteLine($"After method call:{a1.Val}");
//        }
//    }
//}
/*
预计结果：
    Before method call:20
    Bfter member assigment:50
    After member assigment:20
    After method call:20
结果一致，证明完毕
*/


//四、输出参数
//    1. 必须在声明和调用中都是用修饰符out
//    2. 参数必须是变量
//    3. 在方法内部，给输出参数复制后才能读取
//    4. 在方法内部，在方法返回之前，代码中每条可能的路径都必须为所有输出参数赋值

//namespace cs_basic_05
//{
//    class MyClass
//    {
//        public int Val = 20;
//    }
//    class Program
//    {
//        static void RefAsParameter(out MyClass f1, out int f2)
//        {
//            f1 = new MyClass();
//            f1.Val = 25;
//            f2 = 15;
//        }
//        static void Main(string[] args)
//        {
//            MyClass a1 = null;
//            int a2;
//            RefAsParameter(out a1, out a2);
//            Console.WriteLine($"a1：{a1.Val}，a2：{a2}");
//        }
//    }
//}

/*
五、参数数组
    1. 一个参数列表只能又一个参数数组
    2. 必须是列表的最后一个
    3. 参数数组中的所有参数必须是同意类型
    4. 在数据类型前使用params修饰符
    5. 在数据类型后放置一组空的方括号
    void ListInts(params int[] inVals)
    { ... }
    6. 方法调用:
     ListInts(10,20,30,40)
     ListInts(Array)
*/

//namespace cs_basic_05
//{
//    class MyClass
//    {
//        public void ListInts(params int[] inVals)
//        {
//            if((inVals != null) &&(inVals.Length != 0)) 
//            {
//                for(int i = 0; i < inVals.Length; i++)
//                {
//                    inVals[i] = inVals[i] * 10;
//                    Console.WriteLine($"{inVals[i]}");
//                }
//            }
//        }
//    }
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            MyClass myClass = new MyClass();
//            myClass.ListInts(10,20,30,40);
//        }
//    }
//}

//namespace cs_basic_05
//{
//    class MyClass
//    {
//        public void ListInts(params int[] inVals)
//        {
//            if ((inVals != null) && (inVals.Length != 0))
//            {
//                for (int i = 0; i < inVals.Length; i++)
//                {
//                    inVals[i] = inVals[i] * 10;
//                    Console.WriteLine($"{inVals[i]}");
//                }
//            }
//        }
//    }
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            int [] inVals = new int[] { 5,6,7};
//            MyClass myClass = new MyClass();
//            myClass.ListInts(inVals);
//            foreach (int i in inVals)
//            {
//                Console.WriteLine($"{i}");
//            }
//        }
//    }
//}

//六、方法重载
//    1. 签名需要不同（名称、参数数目、参数数据类型和顺序、参数修饰符）

namespace cs_basic_05
{
    class MyClass
    {
        long AddValues(int a, int b) 
        {
            return a + b;
        }
        long AddValues(float a, int b)
        {
            return (long)(a + b);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {

        }
    }
}